/*
 * @Author: weidewei
 * @Date: 2025-05-13 16:21:10
 * @LastEditors: weidewei
 * @LastEditTime: 2025-05-16 15:55:57
 * @Description:
 * @FilePath: \v2\vue.config.js
 */
const { defineConfig } = require("@vue/cli-service");
const path = require("path");
const CompressionPlugin = require("compression-webpack-plugin");
module.exports = defineConfig({
  lintOnSave: false,
  transpileDependencies: true,
  configureWebpack: {
    resolve: {
      alias: {
        utils: path.resolve(__dirname, "./src/utils"),
        api: path.resolve(__dirname, "./src/api"),
        components: path.resolve(__dirname, "./src/components"),
      },
    },
    /**
     * 配置输出文件的命名规则
     *
     * 该配置用于定义Webpack打包后生成的文件命名规则，包含两部分：
     * 1. filename: 主入口文件的命名规则，适用于入口点直接输出的文件
     * 2. chunkFilename: 非入口文件（代码分割/懒加载文件）的命名规则
     */
    output: {
      /**
       * 入口文件命名模板
       * - [name]: 使用入口点名称作为文件名
       * - [contenthash:8]: 基于文件内容生成8位哈希值，用于长期缓存
       * - 输出路径：最终文件将生成在/js目录下
       */
      filename: "js/[name].[contenthash:8].js",

      /**
       * 代码分割块文件命名模板
       * - [name]: 自动生成的模块名称或第三方库名称
       * - [contenthash:8]: 8位内容哈希保证文件内容变化时文件名改变
       * - 添加.chunk后缀用于区分代码分割文件
       * - 输出路径：最终文件将生成在/js目录下
       */
      chunkFilename: "js/[name].[contenthash:8].chunk.js",
    },
    /**
     * Webpack 优化配置对象
     * 包含代码分割策略和运行时分包配置
     */
    optimization: {
      /**
       * 代码分割配置
       * 作用：将 node_modules 中的依赖包分离打包，优化缓存策略和加载性能
       * 配置策略：
       * 1. 处理所有类型的 chunk（同步/异步）
       * 2. 设置代码分割的最小/最大体积限制
       * 3. 通过缓存组定义具体分包规则
       */
      splitChunks: {
        chunks: "all", // 同时处理同步和异步引入的模块
        minSize: 20000, // 生成 chunk 的最小体积（20KB）
        maxSize: 500000, // 尝试拆分超过此体积的 chunk（500KB）

        /**
         * 缓存组配置（优先级顺序：vue > elementUI > vendors）
         * 匹配规则：
         * - 使用正则表达式匹配 node_modules 中的特定依赖包
         * - 根据 priority 数值决定匹配优先级
         * - 匹配到的模块会被打包到指定的 chunk 文件中
         */
        cacheGroups: {
          // Vue 核心框架分包规则
          vue: {
            test: /[\\/]node_modules[\\/](vue|vue-router|vuex)[\\/]/, // 匹配 Vue 生态相关包
            name: "chunk-vue", // 输出文件名
            priority: 30, // 优先级最高（数值越大优先级越高）
          },

          // Element UI 组件库分包规则
          elementUI: {
            test: /[\\/]node_modules[\\/]element-ui[\\/]/, // 匹配 ElementUI 包
            name: "chunk-element", // 输出文件名
            priority: 20, // 次高优先级
          },

          // 通用依赖分包规则（兜底策略）
          vendors: {
            test: /[\\/]node_modules[\\/]/, // 匹配所有 node_modules 中的模块
            name: "chunk-vendors", // 输出文件名
            priority: 10, // 最低优先级
          },
        },
      },

      /**
       * 运行时分包配置
       * 作用：将 webpack 运行时代码提取为独立文件，避免修改业务代码导致 vendor 缓存失效
       * 特性：为每个入口生成独立的 runtime 文件
       */
      runtimeChunk: {
        name: (entrypoint) => `runtime-${entrypoint.name}`, // 动态生成 runtime 文件名
      },
    },
    externals: {
      vue: "Vue",
      "vue-router": "VueRouter",
      axios: "axios",
      elementUI: "ElementUI",
      vuex: "Vuex",
    },
    plugins: [
      new CompressionPlugin({
        test: /\.(js|css)(\?.*)?$/i,
        threshold: 1024, // 压缩所有文件
        // minRatio: 0.8, // 仅压缩后体积/原体积 <0.8 的文件
        deleteOriginalAssets: false, // 保留原始文件
      }),
    ],
    profile: true,
    stats: {
      chunks: true,
      chunkModules: true,
      chunkOrigins: true,
      modules: false,
      cached: false,
      reasons: false,
    },
  },
  css: {
    extract: {
      filename: "css/[name].[contenthash:8].css",
      chunkFilename: "css/[name].[contenthash:8].chunk.css",
    },
  },
  chainWebpack: (config) => {
    // 添加 Worker 配置规则（放在其他chainWebpack配置之前）
    config.module
      .rule("worker")
      .test(/\.worker\.js$/)
      .use("worker-loader")
      .loader("worker-loader")
      .options({
        inline: "fallback", // 兼容旧浏览器
        filename: "js/[name].[contenthash:8].worker.js", // 输出文件名格式
      })
      .end();
    // config.plugin('webpack-bundle-analyzer')
    //   .use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin, [{
    //     analyzerMode: 'static',
    //     reportFilename: 'report.html',
    //     openAnalyzer: true
    //   }])
  },
  devServer: {
    // progress: true,
    // 开启了mock，proxy就不会生效
    proxy: {
      "/api": {
        target: "http://shanhe.kim/api/za/tianqi.php", // 确保此处是后端真实地址
        changeOrigin: true, // 必须设置！
        pathRewrite: {
          "^/api": "/api", // 移除请求路径中的 /api 前缀
        },
      },
    },
  },
});
